package model_convert

import (
	"strings"
)

type GenerateGRPCInstanceArg struct {
	PackageName   string
	PbPackagePath string
}

func GenerateGRPCInstanceV2(server RpcServer, packageName string, pbPackagePath string) string {
	ss := server.String()
	rs := GenerateGRPCInstance(ss, GenerateGRPCInstanceArg{
		PbPackagePath: pbPackagePath,
		PackageName:   packageName,
	})
	return rs
}

func GenerateGRPCInstance(src string, arg GenerateGRPCInstanceArg) string {
	if arg.PackageName == "" {
		arg.PackageName = "control"
	}

	if arg.PbPackagePath == "" {
		arg.PbPackagePath = "path/to/pb"
	}

	src = trim(src)
	type Method struct {
		MethodName   string
		ReqName      string
		ResponseName string
	}
	type Param struct {
		PbPackageName string
		StructName    string

		Methods []Method
	}

	var param = Param{
		Methods: make([]Method, 0, 10),
	}
	param.PbPackageName = strings.Split(arg.PbPackagePath, "/")[len(strings.Split(arg.PbPackagePath, "/"))-1]

	// 获取structName
	lines := strings.Split(src, "\n")
	firstLineArgs := strings.Split(lines[0], " ")

	param.StructName = strings.TrimSuffix(firstLineArgs[len(firstLineArgs)-1], "{")

	for i, v := range lines {
		if i == 0 || i == len(lines)-1 {
			continue
		}
		if !strings.Contains(v, "rpc ") {
			continue
		}

		v = trim(v)

		lineArgs := strings.Split(v, " ")

		var method Method

		// 获取methodName
		method.MethodName = lineArgs[1][:strings.Index(lineArgs[1], "(")]
		method.ReqName = lineArgs[1][strings.Index(lineArgs[1], "(")+1 : strings.Index(lineArgs[1], ")")]
		method.ResponseName = lineArgs[3][strings.Index(lineArgs[3], "(")+1 : strings.Index(lineArgs[3], ")")]

		param.Methods = append(param.Methods, method)
	}

	var result = templategrpcf

	result = strings.Replace(result, "${package_name}", arg.PackageName, -1)
	result = strings.Replace(result, "${pb_package_path}", arg.PbPackagePath, -1)
	result = strings.Replace(result, "${struct_name}", param.StructName, -1)

	var methodArr = make([]string, 0, 10)
	for _, v := range param.Methods {
		var method = templategrpcmethodf
		method = strings.Replace(method, "${struct_name}", param.StructName, -1)
		method = strings.Replace(method, "${method_name}", v.MethodName, -1)
		method = strings.Replace(method, "${req_name}", v.ReqName, -1)
		method = strings.Replace(method, "${response_name}", v.ResponseName, -1)
		method = strings.Replace(method, "${pb_package_name}", param.PbPackageName, -1)

		methodArr = append(methodArr, method)
	}

	result = strings.Replace(result, "${methods}", strings.Join(methodArr, ""), -1)

	return result
}

func trim(src string) string {
	src = strings.Trim(src, " ")
	src = strings.Trim(src, "\t")
	src = strings.Trim(src, "\n")
	return src
}

var templategrpcf = `

// auto generated by github.com/fwhezfwhez/model_convert.GenerateGRPCInstance
package ${package_name}

import (
	"context"
	// "github.com/fwhezfwhez/errorx"
	// "golang.org/x/protobuf/proto"
	"${pb_package_path}"
)

type ${struct_name} struct{}
${methods}
`

var templategrpcmethodf = `
func (o *${struct_name}) ${method_name}(ctx context.Context, param *${pb_package_name}.${req_name}) (*${pb_package_name}.${response_name}, error) {
	// todo do your work here
    rsp := &${pb_package_name}.${response_name}{
	}
	return rsp, nil
}
`
